package com.tian.core.shiro;


import com.tian.core.base.model.BaseUser;
import com.tian.core.base.service.BaseUserService;
import com.tian.core.lang.Constant;
import com.tian.core.redis.RedisPool;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

/**
 *  shiro的realm
 * @author YangTao
 * @date 2025/4/18
 */
public class ShiroRealm extends AuthorizingRealm {
    //@Autowired
    private BaseUserService baseUserService;
    @Autowired
    private RedisPool redisPool;

    /**
     * 保存权限，角色
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        BaseUser baseUser = baseUserService.findByPhone((String) principalCollection.getPrimaryPrincipal());
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(baseUserService.getRoles(baseUser.getUserId()));
        simpleAuthorizationInfo.setStringPermissions(baseUserService.getPermissions(baseUser.getUserId()));
        principalCollection.getPrimaryPrincipal();
        return simpleAuthorizationInfo;
    }

    /**
     * 登录认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String phone = (String) authenticationToken.getPrincipal();
        BaseUser baseUser = baseUserService.findByPhone(phone);
        String key = Constant.REDIS_LOGIN_PRE + phone;
        // 登录次数+1
        redisPool.incr(key, 1L);
        String loginCount = redisPool.get(key);
        // 判断是否被锁定
        if ("LOCKED".equals(loginCount)) {
            throw new DisabledAccountException();
        }
        // 登录次数超过5次就锁定，锁定时间一个小时
        if (Integer.parseInt(loginCount) >= 5) {
            redisPool.set(key, "LOCKED");
            // 设置过期时间
            redisPool.expire(key, 60);
        }
        // 用户不存在
        if (null == baseUser) {
            throw new UnknownAccountException();
        }
        // 用户被锁定
        if ("0".equals(baseUser.getStatus())) {
            throw new DisabledAccountException();
        }
        return new SimpleAuthenticationInfo(baseUser, baseUser.getPassword(), getName());
    }
}
